/*
 * Copyright (C) 2022-2022. Huawei Technologies Co., Ltd. All rights reserved.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.openlookeng.core.tool;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelWriter;
import com.openlookeng.core.vo.ExcelColumnVo;

import java.io.File;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class ExcelUtil
        extends cn.hutool.poi.excel.ExcelUtil
{
    /**
     * Write excel file
     *
     * @param excelFile    excelFile
     * @param columnVoList excelCorrespondence between and attribute name
     * @param dataList     Data to write
     * @return
     */
    public static Boolean writeExcel(File excelFile, List<ExcelColumnVo> columnVoList, List dataList)
    {
        return writeExcel(excelFile, columnVoList, dataList, "");
    }

    /**
     * Write excel file
     *
     * @param excelFile    excelFile
     * @param columnVoList columnVoList
     * @param dataList     dataList
     * @param sheetName    sheetName
     * @return
     */
    public static Boolean writeExcel(File excelFile, List<ExcelColumnVo> columnVoList, List dataList, String sheetName)
    {
        ExcelWriter writer = ExcelUtil.getWriter(excelFile);
        columnVoList.forEach(a -> {
            writer.addHeaderAlias(a.getPropName(), a.getColumnName());
        });
        if (StrUtil.isNotBlank(sheetName)) {
            writer.renameSheet(sheetName);
        }
        List rows = CollUtil.newArrayList(dataList);
        writer.write(rows, true);
        writer.close();
        return true;
    }

    /**
     * Read excel as object
     * @param excelFile         excelFile
     * @param excelColumnVoList excelColumnVoList
     * @param clazz             clazz
     * @return
     */
    public static List readExcel(File excelFile, List<ExcelColumnVo> excelColumnVoList, Class clazz)
    {
        ExcelReader reader = getReader(excelFile);
        List<Map<String, Object>> readAll = reader.readAll();
        Method[] methods = ReflectUtil.getMethods(clazz);
        List objList = readAll.stream().map(m -> {
            Object object = ReflectUtil.newInstance(clazz);
            m.forEach((k, v) -> {
                try {
                    String propName = excelColumnVoList.stream().filter(a -> a.getColumnName().equalsIgnoreCase(k)).findFirst().get().getPropName();
                    char[] chars = propName.toCharArray();
                    if (chars[0] >= 'a' && chars[0] <= 'z') {
                        chars[0] = (char) (chars[0] - 32);
                    }
                    String methodName = "set" + new String(chars);
                    if (StrUtil.isBlank(methodName)) {
                        return;
                    }
                    Method method = Arrays.stream(methods).filter(a -> a.getName().equalsIgnoreCase(methodName)).findFirst().get();
                    ReflectUtil.invoke(object, methodName, Convert.convert(method.getParameterTypes()[0], v));
                }
                catch (Exception e) {
                    e.printStackTrace();
                }
            });
            return object;
        }).collect(Collectors.toList());
        return objList;
    }
}
